package com.jfast.framework.util;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import com.jfast.framework.Jfast;
import com.jfast.framework.exception.InitializationError;

/**
 * 类对象工厂
 * @author zengjintao
 * @version 1.0
 * @createTime 2017年12月10日下午8:04:47
 */
public final class ClassFactory {

	private static final Map<Class<?>,Object> singletons = new ConcurrentHashMap<>();
	
	public static <T> T crateBean(Class<T> cla,boolean createdByGuice){
		if(createdByGuice){
			return Jfast.getBean(cla);
		}
		try {
		    Constructor<T> constructor = cla.getDeclaredConstructor();
		    constructor.setAccessible(true);
			return constructor.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static <T> T createBean(Class<T> cla,Object... params){
		List<Object> list = new ArrayList<>(params.length);
		for (Object object : params) {
			list.add(object);
		}
		return crateBean(cla,list);
	}
	
	
	@SuppressWarnings("unchecked")
	private static <T> T crateBean(Class<T> cla, List<Object> params) {
		try {
			Constructor<T>[] constructors = (Constructor<T>[]) cla.getDeclaredConstructors();
			for (Constructor<T> constructor : constructors) {
				constructor.setAccessible(true);
				if(constructor.getParameterCount() == params.size()){
					return constructor.newInstance(params.toArray());
				}
			}
		} catch (Exception e) {
			throw new InitializationError("can not create bean " + cla,e);
		}
		return null;
	}

	/**
	 * 单例
	 * @param cla
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T crateSingletonsBean(Class<T> cla){
		Object object = singletons.get(cla);
		if(object == null){
			try {
				synchronized (cla) {
					object = singletons.get(cla);
					if(object ==null){
						object = crateBean(cla);
						singletons.put(cla, object);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return (T) object;
	}
	
	
	public static <T> T crateBean(Class<T> cla){
		return crateBean(cla, false);
	}
	
	/**
	 * 创建表单bean
	 * @return
	 */
	public static <T> T createBeanFormRequest(HttpServletRequest request){
		return null;
	}
}
